import { IPageResponse } from "../../../common/CommonType";
import { ValidationError } from "../../../utils/errors";
import SysUserEntity from "./Entity";
import appDataSource from "../../../db";
import SysRoleEntity from "../role/Entity";
import { In } from "typeorm";
import md5 from "md5";

export class SysUserService {
  /**
   * 添加数据
   */
  public static async add(data: SysUserEntity): Promise<true> {
    // 1. 转换类型
    data = SysUserEntity.transform(data);
    // 2. 数据验证
    const errors = await data.validateThis();
    if (errors.length > 0) {
      throw new ValidationError(errors[0]);
    }
    const rep = appDataSource.getRepository(SysUserEntity);
    if (!data.id) {
      const user = await rep.findOneBy({
        loginId: data.loginId,
      });
      if (user) {
        throw new ValidationError("该账号已存在");
      }
    }

    const roleRep = appDataSource.getRepository(SysRoleEntity);
    const roleData = await roleRep.find({
      where: {
        id: In(data.roles as number[]),
      },
    });
    data.roles = roleData;

    data.loginPwd = md5(data.loginPwd);

    await rep.save(data);
    return true;
  }

  /**
   * 分页获取数据
   */
  public static async findByPage(current: number, size: number, where?: any): Promise<IPageResponse> {
    const rep = appDataSource.getRepository(SysUserEntity);
    const [list, total] = await rep.findAndCount({
      skip: size * (current - 1),
      take: size,
      where,
      relations: { roles: true },
    });

    list.forEach((item) => {
      item.roleNames = item.roles.map((role: any) => role.name).join(",");
      item.roles = item.roles.map((role: any) => role.id);
    });

    return {
      total,
      list,
    };
  }

  /**
   * 无分页
   */
  public static async findByList(where?: any) {
    const rep = appDataSource.getRepository(SysUserEntity);
    return rep.find({
      where,
    });
  }

  /**
   * 通过id获取数据
   */
  public static async findById(id: string) {
    const rep = appDataSource.getRepository(SysUserEntity);

    const data = await rep.findOne({
      where: { id: +id },
      relations: { roles: true },
    });
    if (data) {
      data.roles = data.roles.map((role) => role.id);
    }
    return data;
  }

  /**
   * 修改数据
   */
  public static async update(data: any) {
    const rep = appDataSource.getRepository(SysUserEntity);
    data = SysUserEntity.transform(data);

    const user = await rep.findOne({
      where: { id: +data.id },
      relations: { roles: true },
      select: {
        roles: {
          id: true,
        },
      },
    });
    if (!user) {
      throw new Error("用户不存在");
    }

    // 修改数据
    Object.keys(data).forEach((key) => {
      user[key] = data[key];
    });

    // 处理角色
    if (data.roles) {
      // 删除多余role
      const alreadyRole: number[] = [];
      user.roles = (user.roles as SysRoleEntity[]).filter((item) => {
        alreadyRole.push(item.id);
        return data.roles.includes(item.id);
      });
      const sysRoleRep = appDataSource.getRepository(SysRoleEntity);
      for (let i = 0; i < data.roles.length; i++) {
        const id = data.roles[i];

        // 如果这个角色已经保存在user当中，不需要再添加
        if (alreadyRole.includes(id)) {
          continue;
        }

        const role = await sysRoleRep.findOneBy({ id: id });
        role && user.roles.push(role);
      }
    }

    await rep.save(user);
    return null;
  }

  /**
   * 删除数据
   */
  public static async delete(id: string) {
    const rep = appDataSource.getRepository(SysUserEntity);
    const res = await rep.softDelete({ id: +id });
    return res.raw;
  }
}
